In [1]:
import pandas as pd
import struct
import re
import numpy as np

import matplotlib.colors as cols
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D

# %matplotlib inline

Import .pos


In [2]:
def read_pos(f):
    # read in the data
    n = len(file(f).read())/4
    d = struct.unpack('>'+'f'*n,file(f).read(4*n)) 
                    # '>' denotes 'big-endian' byte order
    # unpack data
    pos = pd.DataFrame({'x': d[0::4],
                        'y': d[1::4],
                        'z': d[2::4],
                        'Da': d[3::4]})
    return pos

In [3]:
pos = read_pos('../example-data/voldata.pos')

Import .epos


In [2]:
def read_epos(f):
    # read in the data
    n = len(file(f).read())/4
    rs = n / 11
    d = struct.unpack('>'+'fffffffffII'*rs,file(f).read(4*n)) 
                    # '>' denotes 'big-endian' byte order
    # unpack data
    pos = pd.DataFrame({'x': d[0::11],
                        'y': d[1::11],
                        'z': d[2::11],
                        'Da': d[3::11],
                        'ns': d[4::11],
                        'DC_kV': d[5::11],
                        'pulse_kV': d[6::11],
                        'det_x': d[7::11],
                        'det_y': d[8::11],
                        'pslep': d[9::11], # pulses since last event pulse
                        'ipp': d[10::11]}) # ions per pulse
    return pos

In [3]:
epos = read_epos('../example-data/voldata.epos')

In [4]:
epos


Out[4]:
DC_kV Da det_x det_y ipp ns pslep pulse_kV x y z
0 1997.819946 20.934525 -6.872214 1.240525 2 2372.105469 0 0 -7.853704 0.177746 0.778989
1 1997.819946 47.877735 -9.263744 0.512391 0 3571.510254 0 0 -11.362803 -0.777752 1.655746
2 1998.310059 17.838438 -4.013373 -13.403062 1 2186.283936 8455 0 -4.987985 -18.808384 5.051971
3 1998.310059 20.172239 -14.871471 1.995627 1 2290.781006 4750 0 -20.104198 1.033762 5.434807
4 1998.310059 19.906652 -16.575781 2.912537 1 2266.553467 4124 0 -22.846310 2.005881 7.227716
5 1998.310059 31.967415 6.927192 -8.467931 1 2974.995361 711 0 9.440846 -12.289412 3.123981
6 1998.310059 20.256107 7.119614 1.375364 1 2374.260498 133 0 10.568179 0.351345 1.423205
7 1998.310059 19.981255 4.755572 6.849854 1 2347.825684 5459 0 7.323794 7.526831 1.403526
8 1998.310059 19.852673 -11.490342 12.270409 1 2276.504883 90 0 -15.770174 13.627032 5.859442
9 1998.310059 20.952991 -13.771916 0.782070 1 2340.440674 2767 0 -18.360010 -0.402527 4.465242
10 1998.310059 58.868614 3.216196 15.776239 1 3989.917725 416 0 3.447798 19.047865 4.996380
11 1998.310059 52.711174 9.483655 10.409621 1 3819.000732 2 0 12.152402 11.699831 3.731646
12 1998.310059 21.001070 -14.294205 -0.701166 2 2341.847412 33 0 -19.116055 -2.156364 4.930236
13 1998.310059 73.889610 -14.294205 0.242711 0 4389.881836 0 0 -19.164976 -1.040256 4.906215
14 1998.310059 46.638336 -6.707281 9.088193 1 3527.147949 928 0 -8.245334 10.499295 2.294193
15 1998.810059 20.842909 -12.974740 0.215743 1 2338.300781 1411 0 -17.063606 -1.098804 3.839570
16 1998.810059 114.509758 -6.872214 6.849854 1 5537.262207 5696 0 -8.203526 7.595710 1.594858
17 1998.810059 70.050842 -14.239227 -4.287901 1 4272.949219 4540 0 -19.086325 -6.391914 5.433996
18 1998.810059 56.863289 -12.507429 -1.672012 1 3866.363525 5755 0 -16.329576 -3.420032 3.647018
19 1998.810059 20.096069 -13.661962 0.242711 1 2292.644043 1106 0 -18.146008 -1.049797 4.369767
20 1998.810059 47.758327 -5.167905 -11.380466 1 3576.822754 1855 0 -6.212587 -16.264200 3.989285
21 1998.810059 19.936693 3.985884 2.669825 1 2347.054932 3143 0 6.767699 2.076396 0.632899
22 1998.810059 23.729364 6.157504 13.834549 1 2546.209961 3725 0 7.449194 16.406322 4.289566
23 1998.810059 19.974928 -12.260030 2.427114 1 2291.626465 485 0 -16.030622 1.642075 3.391081
24 1999.550049 56.871922 -1.154532 -2.454082 1 3942.083740 2799 0 0.144892 -4.780421 0.288585
25 1999.550049 19.943424 8.054235 0.701166 1 2356.579834 6267 0 11.674411 -0.549041 1.747138
26 1999.550049 19.886377 -2.803863 -5.717201 1 2323.889893 3747 0 -2.281883 -9.127699 1.124040
27 1999.550049 19.928270 -6.157504 5.690233 1 2311.985596 3044 0 -7.038489 6.091938 1.100000
28 1999.550049 72.649757 -4.755572 -11.299563 1 4414.565430 4560 0 -5.641009 -16.209421 3.870985
29 1999.550049 22.887909 -10.555720 13.349126 1 2441.009521 1295 0 -14.518748 15.085654 5.919090
... ... ... ... ... ... ... ... ... ... ... ...
581664 3826.469971 32.196796 8.081723 4.962099 1 2155.232666 4952 0 11.841788 5.074231 74.993416
581665 3826.469971 20.538071 6.817236 12.863703 1 1709.634766 7862 0 8.782279 15.604765 77.016571
581666 3826.469971 15.241919 -4.535661 -2.076531 1 1462.802856 2134 0 -4.636207 -4.403378 73.430397
581667 3826.469971 19.977034 9.071322 12.378281 1 1690.869263 1539 0 11.559138 14.689123 77.404861
581668 3826.469971 70.007729 8.604012 10.625365 1 3168.224609 538 0 11.458441 12.465487 76.563248
581669 3826.469971 118.858452 1.786776 -10.517493 1 4104.845215 591 0 3.017040 -15.784414 76.188423
581670 3826.469971 69.942970 8.686479 10.679300 1 3166.795410 1585 0 11.541102 12.525889 76.609314
581671 3826.469971 1.006718 -8.384101 -8.306123 1 372.736176 2328 0 -10.715929 -12.524054 76.366165
581672 3826.469971 189.375351 -10.830609 1.591108 1 5099.558105 945 0 -14.230931 0.636855 75.468948
581673 3826.469971 31.979967 -9.703567 -11.892858 1 2089.994873 728 0 -13.056820 -16.742994 78.810608
581674 3826.719971 19.983887 11.242942 6.984694 1 1700.274414 2088 0 15.188375 7.500197 76.568558
581675 3826.719971 19.987539 9.676077 -0.539359 1 1702.444336 2639 0 13.898265 -2.156302 75.403427
581676 3826.719971 26.701336 9.511144 -1.429300 1 1967.084106 1652 0 13.696257 -3.331176 75.414795
581677 3826.719971 48.039261 6.872214 13.537901 1 2613.123779 2524 0 8.655940 16.442472 77.351486
581678 3826.719971 32.015079 11.325409 -3.317055 2 2156.339844 4394 0 15.587741 -5.651480 76.409912
581679 3826.719971 40.002464 11.792719 -2.615889 0 2411.357422 0 0 16.156013 -4.737066 76.523239
581680 3826.719971 1.006827 -6.872214 -9.843295 2 373.357208 147 0 -8.645018 -14.660241 76.605698
581681 3826.719971 5.995399 -6.569837 -13.025511 0 908.824463 0 0 -8.612690 -18.686831 78.426849
581682 3826.719971 198.779480 -6.075037 -0.997813 1 5272.555176 519 0 -6.858701 -2.882880 73.611435
581683 3826.719971 11.988260 -6.789747 -13.780613 1 1283.842285 109 0 -9.030082 -19.549894 78.995171
581684 3826.719971 47.880432 -15.201337 -3.424927 1 2542.416504 2255 0 -21.235893 -5.415766 79.230972
581685 3826.719971 52.098934 -9.291233 -10.544461 1 2673.842285 2011 0 -12.313854 -15.189130 77.858566
581686 3826.719971 1.008150 -13.689450 2.966472 1 369.526276 1551 0 -18.884157 2.310231 77.579315
581687 3826.719971 70.001663 8.164190 -6.984694 1 3177.734375 1496 0 11.475754 -10.643107 76.016937
581688 3826.719971 19.998220 7.174592 14.319971 1 1684.771240 2443 0 8.759223 17.437731 77.838272
581689 3826.719971 70.058533 5.085438 14.832362 1 3145.568115 392 0 6.122859 18.300282 77.723053
581690 3826.719971 6.003592 8.604012 -6.930758 4 930.597778 3703 0 12.005523 -10.538718 76.152664
581691 3826.719971 6.099520 13.881872 -3.182216 0 942.300049 0 0 18.360214 -5.284429 77.623199
581692 3826.719971 12.014996 3.161218 -6.040816 0 1310.366943 0 0 5.551716 -9.742305 74.489265
581693 3826.719971 48.198032 9.291233 -8.818514 0 2636.176758 0 0 12.392248 -12.898662 77.012749

581694 rows × 11 columns


In [5]:
len(epos.loc[epos.ipp != 1, :]) / float(len(epos))


Out[5]:
0.1952796487500301

In [6]:
len(epos)


Out[6]:
581694

Import .rrng


In [7]:
def read_rrng(f):
    rf = open(f,'r').readlines()

    patterns = re.compile(r'Ion([0-9]+)=([A-Za-z0-9]+).*|Range([0-9]+)=(\d+.\d+) +(\d+.\d+) +Vol:(\d+.\d+) +([A-Za-z:0-9 ]+) +Color:([A-Z0-9]{6})')

    ions = []
    rrngs = []
    for line in rf:
        m = patterns.search(line)
        if m:
            if m.groups()[0] is not None:
                ions.append(m.groups()[:2])
            else:
                rrngs.append(m.groups()[2:])

    ions = pd.DataFrame(ions, columns=['number','name'])
    ions.set_index('number',inplace=True)
    rrngs = pd.DataFrame(rrngs, columns=['number','lower','upper','vol','comp','colour'])
    rrngs.set_index('number',inplace=True)
    
    rrngs[['lower','upper','vol']] = rrngs[['lower','upper','vol']].astype(float)
    rrngs[['comp','colour']] = rrngs[['comp','colour']].astype(str)
    
    return ions,rrngs

In [8]:
ions, rrngs = read_rrng('../example-data/rangefile.rrng')

Assign ion labels


In [9]:
def label_ions(pos,rrngs):
    pos['comp'] = ''
    pos['colour'] = '#FFFFFF'
    
    for n,r in rrngs.iterrows():
        pos.loc[(pos.Da >= r.lower) & (pos.Da <= r.upper),['comp','colour']] = [r['comp'],'#' + r['colour']]
    
    return pos

In [10]:
lpos = label_ions(pos,rrngs)


---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
<ipython-input-10-2a775411dbc1> in <module>()
----> 1 lpos = label_ions(pos,rrngs)

NameError: name 'pos' is not defined

Deconvolve Complex Ions


In [28]:
def deconvolve(lpos):
    """Takes a composition-labelled pos file, and deconvolves
    the complex ions. Produces a dataframe of the same input format
    with the extra columns:
       'element': element name
       'n': stoichiometry
    For complex ions, the location of the different components is not
    altered - i.e. xyz position will be the same for several elements."""
      
    out = []
    pattern = re.compile(r'([A-Za-z]+):([0-9]+)')

    for g,d in lpos.groupby('comp'):
        if g is not '':
            for i in range(len(g.split(' '))):
                tmp = d.copy()
                cn = pattern.search(g.split(' ')[i]).groups()
                tmp['element'] = cn[0]
                tmp['n'] = cn[1]
                out.append(tmp.copy())
    return pd.concat(out)

In [29]:
dpos = deconvolve(lpos)